import { configByID, gameConfig, gameConfigHandle, propName } from "js/config/gameConfig"
import { GameRouteData, localApi } from "js/core/localApi"
import utils from "js/core/utils"
import bagHandle from "js/handle/bagHandle"
import equipmentHandle from "js/handle/equipmentHandle"
import playerHandle from "js/handle/playerHandle"
import { ItemModel } from "js/model/itemModel"
import { BagType, ConditionType, CreateKind, EquipmentItemType, ItemType, SkillType, TaskType } from "js/typeDefine/typeDefine"
import adventureHandle from "js/handle/adventureHandle"
import marketHandle from "js/handle/marketHandle"
import taskHandle from "js/handle/taskHandle"
import gameUtils from "js/core/gameUtils"
import treasureHandle from "js/handle/treasureHandle"
import partnerHandle from "js/handle/partnerHandle"
import { PartnerModel } from "js/model/partnerModel"
import { TaskInfo } from "js/model/taskModel"

class NormalRoute {
    @localApi('normalRoute')
    dieInfor(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.baseInfo.haveShowDieInfor = true
        return { err: 0 }
    }
    //通关地图获得该地图5分钟的经验收益
    @localApi('normalRoute')
    getPassMapExp(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let expAmount = adventureHandle.getGoldAndExpAmount(player, time)[1] * 5
        player.teamList.list.forEach(p => {
            if (p) {
                p.exp += expAmount
            }
        })
        // player.partner.exp += expAmount
        player.itemInfo.gold += expAmount * 2
        return { err: 0, data: expAmount }
    }
    //进入深渊
    @localApi('normalRoute')
    getInDeep(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let diamond = player.itemInfo.diamond
        let freeTimes = gameConfigHandle.gameConfig.map.deepFreeTimes
        if (playerHandle.isMember(player, time)) {
            freeTimes += gameConfigHandle.gameConfig.vip.deepTimesOfAfd
        }
        if (player.baseInfo.longVip) {
            freeTimes += gameConfigHandle.gameConfig.vip.deepTimesOfLongVip
        }
        let maxTimes = gameConfigHandle.gameConfig.map.deepTimesMax + gameConfig.vip.addDeepTimes[playerHandle.getVipLvl(player)]
        let deepTimes = player.deepInfo.times
        let costConfig = gameConfigHandle.gameConfig.map.deepCost
        let costLvl = deepTimes - freeTimes
        if (deepTimes < freeTimes) {
            // return {
            //     err: 2
            // }
        } else if (deepTimes < maxTimes) {
            let cost = utils.getIncValue(costConfig, costLvl)
            if (diamond < cost) {
                return { err: 1 }//魂晶不足
            } else {
                player.itemInfo.diamond -= cost
            }
        } else {
            return { err: 2 }//今日次数已达上限
        }
        player.deepInfo.times += 1
        player.deepInfo.totalTimes = (player.deepInfo.totalTimes || 0) + 1
        return { err: 0 }
    }
    //深渊杀敌数量更新,战利品结算
    @localApi('normalRoute')
    refreshDeepKillAmount(killAmount: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        if (player.deepInfo.progress <= killAmount) {
            player.deepInfo.progress = killAmount
        }
        let mapID = gameConfigHandle.gameConfig.map.deepMapID
        let mapConfig = gameConfigHandle.configByID[mapID]
        let freeTimes = gameConfigHandle.gameConfig.map.deepFreeTimes
        if (playerHandle.isMember(player, time)) {
            freeTimes += gameConfigHandle.gameConfig.vip.deepTimesOfAfd
        }
        let dropList: any[] = []
        let deepTimes = player.deepInfo.times || 0
        if (player.deepInfo.progress < killAmount) {
            player.deepInfo.progress = killAmount
        }

        // 宝物

        let day = new Date(dayTime)
        let itemIDs = mapConfig.drops.items
        let tID: number = utils.getOneFromArray(itemIDs, random)
        let treasure = treasureHandle.createTreasure(tID, 1, random)
        bagHandle.AddItemComponent(player.treasureBag, treasure)
        let itemName = configByID[tID].name
        dropList.push({ name: itemName, num: 1 })
        // 材料
        let resourceAmountConfig = mapConfig.resourceAmount
        let amountOfResource = utils.getIncValue(resourceAmountConfig, killAmount - 1)
        let dropIDList = mapConfig.drops.resources
        let kind: string = ''
        if (deepTimes <= freeTimes) {
            kind = '日常挑战获得宝物和材料'
            for (let i = 0; i < dropIDList.length; i++) {
                tID = dropIDList[i]
                bagHandle.AddItem(player.bag, tID, amountOfResource, random)
                let itemName = configByID[tID].name
                dropList.push({ name: itemName, num: amountOfResource })
            }
        } else {
            kind = '魂晶挑战仅获得宝物'
        }
        return { err: 0, data: [kind, dropList] }
    }
    @localApi('normalRoute')
    levelUp(index: number, gamRouteData?: GameRouteData) {
        let lvlMax = gameConfigHandle.gameConfig.base.levelMax
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[index]
        if (partner.lvl >= lvlMax) {
            return { err: 6 }
        }
        let needExp = playerHandle.getLvlUpExp(player, index)
        let exp = partner.exp
        if (needExp > exp) {
            return { err: 1 }
        }
        partner.exp -= needExp
        player.itemInfo.usedItemStat['exp'] = (player.itemInfo.usedItemStat['exp'] || 0) + needExp
        partner.lvl += 1
        player.teamList.list[index] = partner
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    @localApi('normalRoute')
    campPartnerlevelUp(index: number, gamRouteData?: GameRouteData) {
        let lvlMax = gameConfigHandle.gameConfig.base.levelMax
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.camp[index]
        if (partner.lvl >= lvlMax) {
            return { err: 6 }
        }
        let needExp = playerHandle.getLvlUpExp(player, index, true)
        let exp = partner.exp
        if (needExp > exp) {
            return { err: 1 }
        }
        partner.exp -= needExp
        player.itemInfo.usedItemStat['exp'] = (player.itemInfo.usedItemStat['exp'] || 0) + needExp
        partner.lvl += 1
        partner.fighter = partnerHandle.createPartnerFighter(player, partner)
        player.teamList.camp[index] = partner
        return { err: 0 }
    }
    //切换装备方案
    // @localApi('normalRoute')
    // changeEquipmentsPlan(planIndex: number, gamRouteData?: GameRouteData) {
    //     let { player, time, dayTime, random, } = gamRouteData
    //     let vip = playerHandle.getVipLvl(player)
    //     let unLockVipLvl = gameConfigHandle.gameConfig.partner.unLockEquipmentsPlanVipLvl
    //     if (vip < unLockVipLvl[planIndex]) {
    //         return { err: 1 }
    //     }
    //     player.partner.equipmentActive = planIndex
    //     //更新角色属性 并刷新显示
    //     playerHandle.initTeam(player)
    //     return { err: 0 }
    // }
    //一键穿装备
    @localApi('normalRoute')
    oneKeyPutOnEquipments(pIndex: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        //先把装备整理一下
        bagHandle.arrange(player, BagType.Equipment)
        equipmentHandle.oneKeyPutOnEquipments(player, pIndex)
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    //一键脱下装备
    @localApi('normalRoute')
    oneKeyTakeOffEquipments(index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[index]
        let activeIndex = equipmentHandle.getEquipmentActive(player, partner)
        let equipmentsOn = partner.equipments[activeIndex]
        let equipmentBag = equipmentHandle.getEquipmentBag(player)
        let parts = gameConfigHandle.gameConfig.equipment.equipmentParts
        let n = 0
        let isFull = false
        for (let i = 0; i < parts.length; i++) {
            let equip = equipmentsOn[parts[i]]
            if (equip) {
                if (equip.equipment.gems) {
                    for (let i = 0; i < equip.equipment.gems.length; i++) {
                        let gem = equip.equipment.gems[i];
                        if (gem) {
                            equip.equipment.gems[i] = null
                            bagHandle.AddItem(player.bag, gem.tID, 1, random, gem.hp)
                        }
                    }
                }
                let res = bagHandle.AddItemComponent(equipmentBag, equip)
                if (res) {
                    n++
                    equipmentsOn[parts[i]] = null
                } else {
                    isFull = true
                }
            }
        }
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0, data: [isFull, n] }
    }
    @localApi('normalRoute')
    equipmentPutOn(itemPos: number, pIndex: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[pIndex]
        let bag = equipmentHandle.getEquipmentBag(player)
        let equipment = bag.items[itemPos]
        if (!equipment) {
            return { err: 100 }
        }
        let tID = equipment.tID
        let gameConfig = configByID[tID]
        let lvl = equipment.equipment.lvl
        if (partner.lvl < lvl) {
            return { err: 1 }
        }

        let equipments = partner.equipments
        let equipmentActive = equipmentHandle.getEquipmentActive(player, partner)

        //把装备栏的装备放到背包  要考虑装备栏没有装备的情况
        let part = equipmentHandle.equipmentKindToPart[gameConfig.equipmentKind]
        let equipmentOff: ItemModel = equipments[equipmentActive][part]
        // 判断是否可以佩戴装备
        if (gameConfig.equipmentKind == EquipmentItemType.Hand
            || gameConfig.equipmentKind == EquipmentItemType.SubHand) {
            let partnerConfig = configByID[partner.tID]
            if (gameConfig.equipmentKind == EquipmentItemType.Hand
                && partnerConfig.mainHand.findIndex(n => n == tID) == -1) {
                return {
                    err: 2
                }
            } else if (gameConfig.equipmentKind == EquipmentItemType.SubHand
                && partnerConfig.subHand.findIndex(n => n == tID) == -1) {
                return {
                    err: 2
                }
            }
        }
        //把该装备从背包移除
        bagHandle.removeItemByPosition(bag, itemPos)
        let gems: ItemModel[] = []
        if (equipmentOff) {
            for (let i = 0; i < equipmentOff.equipment.gems.length; i++) {
                if (equipmentOff.equipment.gems[i]) {
                    gems.push(equipmentOff.equipment.gems[i])
                }
                equipmentOff.equipment.gems[i] = null
            }

            for (let i = 0; i < gems.length; i++) {
                if (equipment.equipment.gems.length >= i + 1 && player.gameSet.autoEquipGem) {
                    if (equipment.equipment.gems[i]) {
                        bagHandle.AddItemComponent(player.bag, equipment.equipment.gems[i])
                    }
                    equipment.equipment.gems[i] = gems[i]
                } else {
                    if (player.gameSet.autoEquipHole && player.gameSet.autoEquipGem) {
                        let addHoleNeed = gameConfigHandle.gameConfig.equipment.addHoleNeed
                        let needItemID = addHoleNeed[0]
                        let needAmount = addHoleNeed[1]
                        let haveAmount = bagHandle.getTotalNumByItemId(player.bag, needItemID)
                        if (needAmount <= haveAmount) {
                            bagHandle.removeItemByItemId(player.bag, needItemID, needAmount)
                            equipment.equipment.gems[i] = gems[i]
                        } else {
                            bagHandle.AddItemComponent(player.bag, gems[i])
                        }
                    } else {
                        bagHandle.AddItemComponent(player.bag, gems[i])
                    }
                }
            }
            bagHandle.AddItemComponent(bag, equipmentOff)
        }

        //把装备放到装备栏
        equipments[equipmentActive][part] = equipment
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }

    }
    @localApi('normalRoute')
    equipmentTakeOff(part: string, index: number, gamRouteData?: GameRouteData) {
        //要考虑背包是否有空间放置脱下的装备
        let { player, time, dayTime, random, } = gamRouteData
        let bag = equipmentHandle.getEquipmentBag(player)
        if (!bagHandle.IsHasEmpty(bag)) {
            return { err: 1 }//背包空间不足
        }

        //把装备栏的装备放到背包  要考虑装备栏没有装备的情况
        let partner = player.teamList.list[index]
        let equipments = partner.equipments
        let equipmentActive = equipmentHandle.getEquipmentActive(player, partner)
        let equipmentOff = equipments[equipmentActive][part]
        if (equipmentOff == null) {
            return { err: 2 }//该部位没有装备
        }
        if (equipmentOff.equipment.gems) {
            for (let i = 0; i < equipmentOff.equipment.gems.length; i++) {
                let gem = equipmentOff.equipment.gems[i];
                if (gem) {
                    equipmentOff.equipment.gems[i] = null
                    bagHandle.AddItem(player.bag, gem.tID, 1, random, gem.hp)
                }
            }
        }
        bagHandle.AddItemComponent(bag, equipmentOff)

        //该装备栏清空
        equipments[equipmentActive][part] = null

        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }

    }
    //背包扩容
    @localApi('normalRoute')
    addBagCapacity(bagType: BagType = BagType.Bag, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let amount = bagHandle.getTotalNumByItemId(player.bag, 170012)
        if (player.baseInfo.addBagCapacity >= 100) {
            return { err: 2 }
        }
        if (amount < 2) {
            return { err: 1 }
        }
        bagHandle.removeItemByItemId(player.bag, 170012, 2)
        if (bagType == BagType.Bag) {
            player.baseInfo.bagAddSize += 1
        } else if (bagType == BagType.Equipment) {
            player.baseInfo.eqBagAddSize += 1
        } else if (bagType == BagType.Equipment2) {
            player.baseInfo.eqBag2AddSize += 1
        } else if (bagType == BagType.Treasure) {
            player.baseInfo.trBagAddSize += 1
        }
        //更新角色属性 并刷新显示
        playerHandle.initBag(player)
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    @localApi('normalRoute')
    changeAnimation(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.baseInfo.closeAnimation = !player.baseInfo.closeAnimation
        return { err: 0 }
    }
    @localApi('normalRoute')
    arrange(bagType: BagType, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        bagHandle.arrange(player, bagType)
        return { err: 0 }
    }
    @localApi('normalRoute')
    changeEquipmentAttriChose(index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.baseInfo.equipmentAttriChose[index] = !player.baseInfo.equipmentAttriChose[index]
        return { err: 0 }
    }
    @localApi('normalRoute')
    lockAll(bagType: BagType, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        if (bagType == BagType.Bag) {
            let items = player.bag.items
            for (let i = 0; i < items.length; i++) {
                if (items[i]) {
                    items[i].lock = 1
                }
            }
        } else if (bagType == BagType.Equipment) {
            let items = player.equipmentBag.items
            for (let i = 0; i < items.length; i++) {
                if (items[i]) {
                    items[i].lock = 1
                }
            }
        } else if (bagType == BagType.Treasure) {
            let items = player.treasureBag.items
            for (let i = 0; i < items.length; i++) {
                if (items[i]) {
                    items[i].lock = 1
                }
            }
        }
        return { err: 0 }
    }

    @localApi('normalRoute')
    sellEquipment(bagType: BagType, itemPos: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        //获得金币 清除该装备
        let data = ''
        let getItems = {}
        if (bagType == BagType.Equipment || bagType == BagType.Equipment2) {
            let bag = bagType == BagType.Equipment ? player.equipmentBag : player.equipmentBag2
            let equipment = bag.items[itemPos]
            if (!equipment) {
                return { err: 100 }
            }
            if (equipment.lock == 1) {
                return { err: 1 }
            }
            if (equipment.equipment.gems.find(eitem => eitem)) {
                return { err: 2 }
            }
            let getData: any = equipmentHandle.getPriceOfEquipment(equipment)
            if (!getItems[getData.itemID]) {
                getItems[getData.itemID] = 0
            }
            getItems[getData.itemID] += getData.amount
            bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
            //返还材料
            let backItems = equipmentHandle.getBackWhenSellItemOfStrengthen(equipment)
            for (let i = 0; i < backItems.usedPropsIds.length; i++) {
                if (typeof backItems.usedPropsIds[i] == 'number') {
                    if (!getItems[backItems.usedPropsIds[i]]) {
                        getItems[backItems.usedPropsIds[i]] = 0
                    }
                    getItems[backItems.usedPropsIds[i]] += backItems.usedPropsAmounts[i]
                    bagHandle.AddItem(player.bag, backItems.usedPropsIds[i], backItems.usedPropsAmounts[i], random)
                }
            }
            bagHandle.removeItemByPosition(bag, itemPos)
        } 
        else if (bagType == BagType.Treasure) {
            let treasure = player.treasureBag.items[itemPos]
            if (!treasure) {
                return { err: 100 }
            }
            if (treasure.lock == 1) {
                return { err: 1 }
            }
            let getData: any = treasureHandle.getPrice(treasure)
            if (!getItems[getData.itemID]) {
                getItems[getData.itemID] = 0
            }
            getItems[getData.itemID] += getData.amount
            bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
            //返还材料
            let backItems = equipmentHandle.getBackWhenSellItemOfStrengthen(treasure)
            for (let i = 0; i < backItems.usedPropsIds.length; i++) {
                if (typeof backItems.usedPropsIds[i] == 'number') {
                    bagHandle.AddItem(player.bag, backItems.usedPropsIds[i], backItems.usedPropsAmounts[i], random)
                }
            }
            bagHandle.removeItemByPosition(player.treasureBag, itemPos)
        }
        return { err: 0, data: getItems }
    }

    @localApi('normalRoute')
    itemLock(bagType: BagType, itemPos: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        if (bagType == BagType.Equipment) {
            let equipment = player.equipmentBag.items[itemPos]
            equipment.lock = (equipment.lock == 0) ? 1 : 0
        } else if (bagType == BagType.Equipment2) {
            let equipment = player.equipmentBag2.items[itemPos]
            equipment.lock = (equipment.lock == 0) ? 1 : 0
        } else if (bagType == BagType.Treasure) {
            let treasure = player.treasureBag.items[itemPos]
            treasure.lock = (treasure.lock == 0) ? 1 : 0
        } else if (bagType == BagType.Bag) {
            let item = player.bag.items[itemPos]
            item.lock = (item.lock == 0) ? 1 : 0
        } else if (bagType == BagType.Gem) {
            // let item = player.gemBag.items[itemPos]
            // item.lock = (item.lock == 0) ? 1 : 0
        }
        return { err: 0 }
    }

    //出售材料,宝石
    @localApi('normalRoute')
    sellItem(itemPos: number, amount: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let item = player.bag.items[itemPos]
        let lock = item.lock
        if (lock == 1) {
            return { err: 2 }
        }
        let haveAmount = player.bag.items[itemPos].stack
        if (haveAmount < amount && amount != 9999) {
            return { err: 1 }
        }
        if (amount == 9999) {
            amount = haveAmount
        }
        let itemKind = gameConfigHandle.configByID[item.tID].kind
        let money, price = 0, prop
        let tID = player.bag.items[itemPos].tID
        if (itemKind == ItemType.Prop) {
            price = configByID[tID].price
            bagHandle.removeItemByItemId(player.bag, tID, amount)
        } else if (itemKind == ItemType.Gem) {
            price = utils.getIncValue2(configByID[tID].price, item.hp)
            bagHandle.removeSomeItemByPosition(player.bag, itemPos, amount)
        }
        money = price * amount
        player.itemInfo.gold += money

        return { err: 0, data: money }
    }

    //升级宝石
    @localApi('normalRoute')
    upGem(itemPos: number, amount: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let gem = player.bag.items[itemPos]
        let lvl = gem.hp
        let lvlMax = gameConfigHandle.gameConfig.gem.gemLvlMax
        if (lvl >= lvlMax) {
            return { err: 1 }//顶级宝石无法继续合成
        }
        let upNum
        let gemUpNeed = gameConfigHandle.gameConfig.gem.gemUpNeedAmount
        if (amount == 1) {
            upNum = 1
        } else if (amount == 9999) {
            upNum = Math.floor(gem.stack / gemUpNeed)
        }
        if (gem.stack < gemUpNeed * upNum || upNum == 0) {
            return { err: 2 }//材料宝石不足
        }
        let gemUpNeedMoneyConfig = gameConfigHandle.gameConfig.gem.gemUpNeedMoney
        let needMoney = utils.getIncValue2(gemUpNeedMoneyConfig, lvl)
        let cost = upNum * needMoney
        let money = player.itemInfo.gold
        if (cost > money) {
            upNum = Math.floor(money / needMoney)
            if (upNum == 0) {
                return { err: 4, data: cost }//金币不足
            }
        }
        cost = upNum * needMoney
        let num = bagHandle.getTotalNumByItemId(player.bag, gem.tID, lvl + 1)
        if (num == 0 && !bagHandle.IsHasEmpty(player.bag)) {
            return { err: 3 }//背包满了无法合成
        }
        player.itemInfo.gold -= cost
        bagHandle.removeSomeItemByPosition(player.bag, itemPos, gemUpNeed * upNum)
        bagHandle.AddItem(player.bag, gem.tID, upNum, random, lvl + 1)
        return { err: 0 }
    }
    //打孔
    @localApi('normalRoute')
    addHole(bagIndex: number, part: string, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let equipment: ItemModel
        if (part) {
            let partner = player.teamList.list[index]
            let equipments = partner.equipments[partner.equipmentActive]
            equipment = equipments[part]
        } else if (bagIndex !== null) {
            equipment = player.equipmentBag.items[bagIndex]
        }
        if (!equipment) {
            return { err: 100 }
        }
        let gems = equipment.equipment.gems
        let openHoleNum = gems.length
        let holeMax = gameConfigHandle.gameConfig.equipment.holeAmountMax
        if (openHoleNum >= holeMax) {
            return { err: 1 }
        }
        let addHoleNeed = gameConfigHandle.gameConfig.equipment.addHoleNeed
        let needItemID = addHoleNeed[0]
        let needAmount = addHoleNeed[1]
        let haveAmount = bagHandle.getTotalNumByItemId(player.bag, needItemID)
        if (needAmount > haveAmount) {
            return { err: 2 }
        }
        bagHandle.removeItemByItemId(player.bag, needItemID, needAmount)
        equipment.equipment.gems.push(null)
        return { err: 0 }
    }
    //一键打孔
    @localApi('normalRoute')
    openAllHoles(bagIndex: number, part: string, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let equipment: ItemModel
        if (part) {
            let partner = player.teamList.list[index]
            let equipments = partner.equipments[partner.equipmentActive]
            equipment = equipments[part]
        } else if (bagIndex !== null) {
            equipment = player.equipmentBag.items[bagIndex]
        }
        if (!equipment) {
            return { err: 100 }
        }
        let gems = equipment.equipment.gems
        let openHoleNum = gems.length
        let holeMax = gameConfigHandle.gameConfig.equipment.holeAmountMax
        if (openHoleNum >= holeMax) {
            return { err: 1 }
        }
        let canOpenAmount = holeMax - openHoleNum
        let openSucc = 0
        for (let i = 0; i < canOpenAmount; i++) {
            let addHoleNeed = gameConfigHandle.gameConfig.equipment.addHoleNeed
            let needItemID = addHoleNeed[0]
            let needAmount = addHoleNeed[1]
            let haveAmount = bagHandle.getTotalNumByItemId(player.bag, needItemID)
            if (needAmount > haveAmount) {
                break
            }
            bagHandle.removeItemByItemId(player.bag, needItemID, needAmount)
            equipment.equipment.gems.push(null)
            openSucc++
        }
        return { err: 0, data: openSucc }
    }
    //取下宝石
    @localApi('normalRoute')
    takeOffGem(bagIndex: number, part: string, holeIndex: number, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let equipment: ItemModel
        if (part) {
            let partner = player.teamList.list[index]
            let equipments = partner.equipments[partner.equipmentActive]
            equipment = equipments[part]
        } else if (bagIndex !== null) {
            equipment = player.equipmentBag.items[bagIndex]
        }
        if (!equipment) {
            return { err: 100 }
        }
        let gems = equipment.equipment.gems
        let gem = gems[holeIndex]
        let res = bagHandle.AddItemComponent(player.bag, gem)
        if (!res) {
            return { err: 1 }
        }
        gems[holeIndex] = null
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    //一键取下宝石
    @localApi('normalRoute')
    takeOffAllGems(bagIndex: number, part: string, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let equipment: ItemModel
        if (part) {
            let partner = player.teamList.list[index]
            let equipments = partner.equipments[partner.equipmentActive]
            equipment = equipments[part]
        } else if (bagIndex !== null) {
            equipment = player.equipmentBag.items[bagIndex]
        }
        if (!equipment) {
            return { err: 100 }
        }
        let gems = equipment.equipment.gems
        let gemAmount = 0
        gems.forEach(gem => {
            if (gem) {
                gemAmount++
            }
        })
        if (gemAmount == 0) {
            return { err: 1 }
        }
        let takeOffAmount = 0
        for (let i = 0; i < gems.length; i++) {
            if (gems[i]) {
                let res = bagHandle.AddItemComponent(player.bag, gems[i])
                if (res) {
                    gems[i] = null
                    takeOffAmount++
                } else {
                    break
                }
            }
        }
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0, data: takeOffAmount }
    }
    //镶嵌宝石
    @localApi('normalRoute')
    putOnGem(bagIndex: number, part: string, holeIndex: number, gemIndex: number, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let equipment: ItemModel
        if (part) {
            let partner = player.teamList.list[index]
            let equipments = partner.equipments[partner.equipmentActive]
            equipment = equipments[part]
        } else if (bagIndex !== null) {
            equipment = player.equipmentBag.items[bagIndex]
        }
        if (!equipment) {
            return { err: 100 }
        }
        let gems = equipment.equipment.gems
        let gemInBag = player.bag.items[gemIndex]
        let gemInHole = gems[holeIndex]
        if (gemInHole) {
            let res = bagHandle.AddItemComponent(player.bag, gemInHole)
            if (!res) {
                return { err: 1 }
            }
        }
        let gem = new ItemModel({ tID: gemInBag.tID, hp: gemInBag.hp, stack: 1, lock: gemInBag.lock })
        gems[holeIndex] = gem
        bagHandle.removeSomeItemByPosition(player.bag, gemIndex, 1)
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    //去地图下一层
    @localApi('normalRoute')
    toNextFloor(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let floor = player.adventureInfo.floor
        let mapID = player.adventureInfo.mapID
        let floorMax = gameConfigHandle.configByID[mapID].maxFloor
        //先判断当前地图层是否通关

        //是否已经达到最大层
        if (floor >= floorMax) {
            player.adventureInfo.floor = 1
            let mapComfig = configByID[player.adventureInfo.mapID]
            player.adventureInfo.mapID = mapComfig.nextMapID
            return { err: 0, data: '当前地图已经通关,进入下一个地图!' }
        }
        player.adventureInfo.floor++
        return { err: 0, data: '进入下一层!' }
    }
    //超出当前地图最大楼层就去下个地图的一层
    @localApi('normalRoute')
    mapFloorFull(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let floor = player.adventureInfo.floor
        let mapConfig = gameConfigHandle.configByID[player.adventureInfo.mapID]
        if (floor > mapConfig.maxFloor) {
            player.adventureInfo.floor = 1
            player.adventureInfo.mapID = mapConfig.nextMapID
            let newMapName = gameConfigHandle.configByID[mapConfig.nextMapID].name
            return { err: 0, data: `进入[${newMapName}]` }
        }
        return { err: 0 }
    }

    //签到
    @localApi('normalRoute')
    signIn(gameRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gameRouteData
        if (player.baseInfo.signIn == 2) {
            return { err: 1 }
        }
        player.baseInfo.signIn = 2
        let vip = playerHandle.getVipLvl(player)
        let signInConfig = gameConfigHandle.gameConfig.vip.signIn
        let diamond = utils.getIncValue(signInConfig.diamond, vip)
        let vipExp = utils.getIncValue(signInConfig.vipExp, vip)
        if (playerHandle.isMember(player, time)) {
            gameUtils.setPlayerTestInfo(player, "signInaddGold", gameConfigHandle.gameConfig.vip.diamondOfAfd, 1)
            diamond += gameConfigHandle.gameConfig.vip.diamondOfAfd
            vipExp += gameConfigHandle.gameConfig.vip.vipExpOfAfd
        }
        player.itemInfo.diamond += diamond
        player.baseInfo.vipExp += vipExp

        return { err: 0, data: [diamond, vipExp] }
    }

    //签到
    @localApi('normalRoute')
    signIn2(gameRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gameRouteData
        if (player.baseInfo.signIn2 == 2) {
            return { err: 1 }
        }
        player.baseInfo.signIn2 = 2
        let diamond = gameConfig.base.adGetDiamond
        player.itemInfo.diamond += diamond
        return { err: 0, data: diamond }
    }

    @localApi('normalRoute')
    addVipExp(value: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.baseInfo.vipExp += value

        return { err: 0 }
    }

    @localApi('normalRoute')
    sellIt(itemPos: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let item = player.bag.items[itemPos]
        if (item.tID != 170009) {
            return { err: 1 }
        }
        let getGold = 20 * item.stack
        player.itemInfo.diamond += getGold
        bagHandle.removeItemByPosition(player.bag, itemPos)
        return { err: 0, data: getGold }
    }
    //根据冒险地图进度 获得收益
    @localApi('normalRoute')
    getResource(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        if (!player.market.townMarketItems || player.market.townMarketItems.length == 0) {
            player.market.townMarketItems = []
            playerHandle.resetTownMarketItems(player, random)
        }
        let updateFlag = false
        let { resourceGetTimes, resourceData } = adventureHandle.getAdventureResource(player, time, random)
        if (resourceGetTimes > 0) {
            updateFlag = true
        }
        if (updateFlag) {
            return { err: 0, data: { resourceGetTimes, resourceData } }
        } else {
            return { err: 1 }
        }
    }

    //一键回收
    @localApi('normalRoute')
    sellItemsByOneKey(quality: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let getFromSell = { money: 0, amount: 0, items: {} }

        player.equipmentBag.items.forEach((item) => {
            if (item && item.equipment.quality == quality && item.equipment.strengthen == 0
                && item.lock == 0 && !item.equipment.gems.find(eitem => !!eitem)) {
                let getData: any = equipmentHandle.getPriceOfEquipment(item)
                if (!getFromSell.items[getData.itemID]) {
                    getFromSell.items[getData.itemID] = 0
                }
                getFromSell.items[getData.itemID] += getData.amount
                bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)

                getFromSell.amount += 1
                bagHandle.removeItemByPosition(player.equipmentBag, item.pos)
            }
        })
        return { err: 0, data: getFromSell }
    }

    //自动回收设置 
    @localApi('normalRoute')
    setAutoSell(bagType: number, quality: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        if (bagType == BagType.Equipment) {
            let set = player.adventureInfo.autoSellSet[bagType] || new Array(6).fill(false)
            set[quality] = !set[quality]
            player.adventureInfo.autoSellSet[bagType] = set
        } else if (bagType == BagType.Treasure) {
            let set = player.adventureInfo.autoSellSet[bagType] || new Array(6).fill(false)
            set[quality] = !set[quality]
            player.adventureInfo.autoSellSet[bagType] = set
        }
        return { err: 0 }
    }
    //自动回收设置 
    @localApi('normalRoute')
    changeAutoChangeGem(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.baseInfo.autoChangeGem = !player.baseInfo.autoChangeGem
        return { err: 0 }
    }
    //存储一键回收相关数据
    @localApi('normalRoute')
    saveAutoSellData(planId: number, state: boolean, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.adventureInfo.autoSellState = state
        player.adventureInfo.autoSellSet = planId
        return { err: 0 }
    }

    //一键回收宝物 回收给定品质且没有锁定的所有宝物
    @localApi('normalRoute')
    sellAllTreasures(quality: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let treasures = player.treasureBag.items
        let amount = 0
        let items = {}
        for (let i = 0; i < treasures.length; i++) {
            let treasure = treasures[i]
            if (treasure && treasure.lock == 0 && (treasure.treasure.quality - 1) == quality) {
                let getData: any = treasureHandle.getPrice(treasure)
                if (!items[getData.itemID]) {
                    items[getData.itemID] = 0
                }
                items[getData.itemID] += getData.amount
                bagHandle.AddItem(player.bag, getData.itemID, getData.amount, random)
                bagHandle.removeItemByPosition(player.treasureBag, i)
                amount++
            }
        }
        return { err: 0, data: { amount, items } }
    }

    //改变装备新物品状态
    @localApi('normalRoute')
    newToOld(bagIndex: number, bagType: BagType, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        if (bagType == BagType.Equipment) {
            let equipment = player.equipmentBag.items[bagIndex]
            if (!equipment) {
                return { err: 100 }
            }
            equipment.new = 0
        } else if (bagType == BagType.Treasure) {
            let treasure = player.treasureBag.items[bagIndex]
            if (!treasure) {
                return { err: 100 }
            }
            treasure.new = 0
        }
        return { err: 0 }

    }

    //保存音量设置
    @localApi('normalRoute')
    saveVolumeSet(type: string, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        if (player.baseInfo[type] == 1) {
            player.baseInfo[type] = 2
        } else if (player.baseInfo[type] == 2) {
            player.baseInfo[type] = 1
        }
        return { err: 0 }
    }

    //更改昵称
    @localApi('normalRoute')
    changeName(name: string, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        if (player.playerName == name) {
            return { err: 1 }
        }
        player.playerName = name
        return { err: 0 }
    }
    //晋爵
    @localApi('normalRoute')
    upVip(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData

        // let p = playerHandle.initPlayer(player,time,dayTime)
        playerHandle.initTeam(player)
        return { err: 0 }
    }

    //强化装备
    @localApi('normalRoute')
    strengthenUp(part: string, bagIndex: number, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let partner = player.teamList.list[index]
        let equipmentItem
        if (part) {
            let active = partner.equipmentActive
            equipmentItem = partner.equipments[active][part]
        } else if (bagIndex !== null) {
            equipmentItem = player.equipmentBag.items[bagIndex]
        }
        if (!equipmentItem) {
            return { err: 100 }
        }
        let strengthen = equipmentItem.equipment.strengthen
        let lvl = equipmentItem.equipment.lvl
        let equipmentConfig = gameConfigHandle.gameConfig.equipment
        if (strengthen >= equipmentConfig.strMax) {
            return { err: 6 }//强化已经满级
        }
        //判断材料是否足够
        let config = gameConfigHandle.gameConfig.equipment.equipmentStrNeed
        let res = playerHandle.getNeedAndUse(player, config, lvl / 5 + strengthen, index)
        if (res != 0) {
            return { err: res }
        }
        equipmentItem.equipment.strengthen++
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }

    }
    //更新普通集市里的装备
    @localApi('normalRoute')
    getMarketItems(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let cost = marketHandle.getRefreshCostOfNormalMarket(player, time).cost
        let diamond = player.itemInfo.diamond
        if (cost > diamond) {
            return { err: 1 }//魂晶不够,刷新失败!
        }
        player.itemInfo.diamond -= cost
        player.market.refreshTimes++
        let marketInfor = marketHandle.getMarketItems(player, random)
        player.market.items = marketInfor.items
        player.market.costs = marketInfor.costs
        return { err: 0 }
    }

    //购买普通集市里的装备
    @localApi('normalRoute')
    buyThisItem(index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let item = player.market.items[index]
        let cost = player.market.costs[index]
        let priceGold = 0, priceDiamond = 0
        let gold = player.itemInfo.gold
        let diamond = player.itemInfo.diamond
        let discount = 1
        if (cost['discount']) {
            discount = cost['discount']
        }
        if (item.equipment) {
            if (cost['gold']) {
                priceGold = Math.floor(cost['gold'] * discount)
                if (gold < priceGold) {
                    return { err: 1 }
                }
            } else if (cost['diamond']) {
                priceDiamond = Math.floor(cost['diamond'] * discount)
                if (diamond < priceDiamond) {
                    return { err: 1 }
                }
            }
            let res = bagHandle.AddItemComponent(player.equipmentBag, item)
            if (!res) {
                return { err: 2 }
            }
        } else if (item.treasure) {
            if (cost['gold']) {
                priceGold = Math.floor(cost['gold'] * discount)
                if (gold < priceGold) {
                    return { err: 1 }
                }
            } else if (cost['diamond']) {
                priceDiamond = Math.floor(cost['diamond'] * discount)
                if (diamond < priceDiamond) {
                    return { err: 1 }
                }
            }
            let res = bagHandle.AddItemComponent(player.treasureBag, item)
            if (!res) {
                return { err: 2 }
            }
        } else if (item.hp > 0 && item.hp < 10) {
            if (cost['gold']) {
                priceGold = Math.floor(cost['gold'] * discount * item.stack)
                if (gold < priceGold) {
                    return { err: 1 }
                }
            } else if (cost['diamond']) {
                priceDiamond = Math.floor(cost['diamond'] * discount * item.stack)
                if (diamond < priceDiamond) {
                    return { err: 1 }
                }
            }
            let res = bagHandle.AddItemComponent(player.bag, item)
            if (!res) {
                return { err: 2 }
            }
        } else {
            if (cost['gold']) {
                priceGold = Math.floor(cost['gold'] * discount * item.stack)
                if (gold < priceGold) {
                    return { err: 1 }
                }
            } else if (cost['diamond']) {
                let normalItemList = gameConfigHandle.gameConfig.base.normalItems
                if (normalItemList.includes(item.tID)) {
                    priceDiamond = Math.floor(cost['diamond'] * discount)
                } else {
                    priceDiamond = Math.floor(cost['diamond'] * discount * item.stack)
                }
                if (diamond < priceDiamond) {
                    return { err: 1 }
                }
            }
            let res = bagHandle.AddItemComponent(player.bag, item)
            if (!res) {
                return { err: 2 }
            }
        }
        player.market.costs.splice(index, 1)
        player.market.items.splice(index, 1)
        if (priceGold > 0) {
            player.itemInfo.gold -= priceGold
        }
        if (priceDiamond > 0) {
            player.itemInfo.diamond -= priceDiamond
        }
        player.market.buyTimes++
        return { err: 0 }
    }

    //领取任务奖励
    @localApi('normalRoute')
    getReward(taskID: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let isPass = taskHandle.isTaskPass(player, taskID)
        if (!isPass) {
            return { err: 1 }//任务未完成
        }
        let taskConfig = configByID[taskID]
        let index = -1
        if (player.task.list[taskID] !== undefined && player.task.list[taskID] !== null) {
            index = player.task.list[taskID]
        }

        //奖励内容
        let rewardConfig = taskConfig.reward[index + 1]
        if (rewardConfig[0] == 'diamond') {
            gameUtils.setPlayerTestInfo(player, "getRewardnaddGold", rewardConfig[1], 1)
            player.itemInfo.diamond += rewardConfig[1]
        } else if (rewardConfig[0] == 'exp') {
            gameUtils.setPlayerTestInfo(player, "getRewardexp", rewardConfig[1], 1)
            player.teamList.list.forEach(p => {
                if (p) {
                    p.exp += rewardConfig[1]
                }
            })
            // player.partner.exp += rewardConfig[1]
        } else if (rewardConfig[0] == 'skillExp') {
            player.baseInfo.skillExp += rewardConfig[1]
        } else if (rewardConfig[0] == 'gold') {
            player.itemInfo.gold += rewardConfig[1]
        } else if (rewardConfig[0] == 'gem') {
            let res = bagHandle.AddItemComponent(player.bag, taskHandle.creatTaskGem(rewardConfig[1]))
            if (!res) {
                return { err: 2 }
            }
        } else if (rewardConfig[0] == 'item') {
            let res = bagHandle.AddItemComponent(player.bag, taskHandle.creatTaskItem(rewardConfig[1]))
            if (!res) {
                return { err: 2 }
            }
        } else if (rewardConfig[0] == 'equipment') {
            let res = bagHandle.AddItemComponent(player.equipmentBag, taskHandle.creatTaskEquipment(player, rewardConfig[1], random))
            if (!res) {
                return { err: 2 }
            }
        } else if (rewardConfig[0] == 'treasure') {
            let res = bagHandle.AddItemComponent(player.treasureBag, taskHandle.creatTaskTreasure(player, rewardConfig[1], random))
            if (!res) {
                return { err: 2 }
            }
        } else if (rewardConfig[0] == 'partner') {
            let partnerInfo = taskHandle.createTaskPartner(player, rewardConfig[1], random)
            let campIndex = (player.teamList.camp || []).findIndex(p => p == null)
            if (campIndex == -1) {
                return { err: 101 }
            }
            let partnerConfig = gameConfigHandle.configByID[partnerInfo.tid]
            if (!partnerConfig) {
                return { err: 3 }
            }

            let partner = new PartnerModel({ tID: partnerInfo.tid, name: partnerConfig.name, quality: partnerInfo.quality })
            partner.index = utils.randomString(16)
            partner.fighter = partnerHandle.createPartnerFighter(player, partner)
            player.teamList.camp[campIndex] = partner
        }
        player.task.doneAmount++
        if (player.task.list[taskID] !== undefined && player.task.list[taskID] !== null) {
            player.task.list[taskID]++
        } else {
            player.task.list[taskID] = 0
        }
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    //部位强化
    @localApi('normalRoute')
    upPartStr(part: string, index: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[index]
        let partLvl = partner.partStr[part] || 0
        if (partLvl >= partner.lvl) {
            return { err: 6 }
        }
        //判断材料是否足够
        let config = gameConfigHandle.gameConfig.equipment.partStrNeed
        let res = playerHandle.getNeedAndUse(player, config, partLvl + 1, index)
        if (res != 0) {
            return { err: res }
        }
        partner.partStr[part] = partLvl + 1
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }
    //属性强化
    @localApi('normalRoute')
    upAttriStrLvl(index: number, attriName: string, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[index]
        let pLvl = partner.lvl
        let attriStrLvls = partner.attriStrLvls
        let strlvl = attriStrLvls[attriName] || 0
        if (strlvl >= pLvl) {
            return { err: 6 }//属性强化等级不能高于角色等级
        }
        if (strlvl >= gameConfig.partner.maxLvl) {
            return { err: 7 }//属性强化等级不能高于角色等级
        }
        //判断是否达到升级条件
        let partnerConfig = gameConfigHandle.gameConfig.partner
        let res = playerHandle.getNeedAndUse(player, partnerConfig.attriStrNeed, strlvl, index)
        if (res !== 0) {
            return { err: res }
        }
        attriStrLvls[attriName] = strlvl + 1
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }

    @localApi('normalRoute')
    getMail(data: any, gameRouteData?: GameRouteData) {

        let { player, random, time, dayTime } = gameRouteData

        let items1 = data.items1
        if (items1) {
            items1.forEach(item => {
                let itemID = item[0]
                let itemAmount = item[1]
                if (itemID == "diamond") {
                    gameUtils.setPlayerTestInfo(player, "getMailaddGold", item[1], 1)
                    player.itemInfo.diamond += item[1]
                } else if (itemID == "gold") {
                    player.itemInfo.gold += item[1]
                } else if (itemID == "exp") {
                    player.teamList.list.forEach(p => {
                        if (p) {
                            p.exp += item[1]
                        }
                    })
                } else if (itemID == "vipExp") {
                    player.baseInfo.vipExp += item[1]
                } else if (itemID == 'vip') {
                    let vipLvl = itemAmount
                    player.baseInfo.vip = player.baseInfo.vip > vipLvl ? player.baseInfo.vip : vipLvl
                } else if (itemID == 'vipTime') {
                    if (player.baseInfo.vipTime <= dayTime) {
                        player.baseInfo.vipTime = dayTime
                    }
                    player.baseInfo.vipTime += item[1]
                } else if (itemID == 'longVip') {
                    player.baseInfo.longVip = true
                } else {
                    let itemConfig = gameConfigHandle.configByID[itemID]
                    if (itemConfig && itemConfig.hurtType) {
                        let index = player.teamList.list.findIndex(p => p == null)
                        if (index != -1) {
                            let count = 0
                            player.teamList.list.forEach(p => {
                                if (p && p.tID == itemID) {
                                    count += 1
                                }
                            })
                            if (count >= 2) {
                                index = -1
                            }
                        }
                        let campIndex = (player.teamList.camp || []).findIndex(p => p == null)
                        if (index == -1) {
                            if (campIndex == -1) {
                                return { err: 1 }
                            }
                        }
                        let partnerConfig = itemConfig
                        let quality = 0, lvl = 1, customFeature = null, star = 0
                        if (item.length > 2) {
                            quality = item[2]
                        }
                        if (item.length > 3) {
                            star = item[3]
                        }
                        if (item.length > 4) {
                            lvl = item[4]
                        }

                        if (item.length > 5) {
                            customFeature = item[5]
                        }
                        let partner = new PartnerModel({ tID: itemID, name: partnerConfig.name, quality, lvl, customFeature, star })
                        partner.index = utils.randomString(16)
                        let pos = 0
                        let emptyArr = new Array(12).fill(1).map(i => pos++)
                        player.teamList.list.forEach((p, i) => {
                            if (p) {
                                emptyArr[p.formationPos] = null
                            }
                        })
                        emptyArr = emptyArr.filter(i => i != null)
                        partner.formationPos = emptyArr.length > 1 ? emptyArr[1] : emptyArr[0]
                        partner.fighter = partnerHandle.createPartnerFighter(player, partner)
                        if (index == -1) {
                            player.teamList.camp[campIndex] = partner
                        } else {
                            player.teamList.list[index] = partner
                        }
                    } else if (itemConfig.kind == ItemType.Gem) {
                        let hp = item.length == 3 ? item[2] : 1
                        let id = Number(itemID)
                        if (gameConfigHandle.gameConfig.items[id]) {
                            bagHandle.AddItem(player.bag, id, itemAmount, random, hp)
                        }
                    } else if (itemConfig.kind == ItemType.Treasure) {
                        let treasureItem = treasureHandle.createTreasureForMail(itemID, item[3], random, item[2])
                        bagHandle.AddItemComponent(player.treasureBag, treasureItem)
                    } else {
                        let id = Number(itemID)
                        if (gameConfigHandle.gameConfig.items[id]) {
                            bagHandle.AddItem(player.bag, id, itemAmount, random)
                        }
                    }
                }
            })
        }
        let items2 = data.items2
        if (items2) {
            items2.forEach(e => {
                let item = new ItemModel(e)
                if (item.equipment) {
                    bagHandle.AddItemComponent(player.equipmentBag, item)
                } else if (item.treasure) {
                    item = treasureHandle.createTreasure(e.tID, item.treasure.lvl || 1, random, item.treasure.quality || 2)
                    bagHandle.AddItemComponent(player.treasureBag, item)
                } else {
                    bagHandle.AddItemComponent(player.bag, item)
                }
            })
        }
        return { err: 0 }
    }

    @localApi('normalRoute')
    activeFormation(index: number, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        player.formation.active = index
        playerHandle.initTeam(player)
        return { err: 0 }
    }

    @localApi('normalRoute')
    upFormation(index: number, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let lvl = player.formation.lvls[index]
        if (lvl >= gameConfig.baseFormation.maxLvl) {
            return {
                err: 6
            }
        }
        let needConfig = gameConfig.baseFormation.lvlUpNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, lvl, index)
        if (res !== 0) {
            return { err: res }
        }
        player.formation.lvls[index] += 1
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    getBattleWorldBossReward(gameRouteData?: GameRouteData) {
        let { player, random } = gameRouteData
        let items = gameConfig.base.worldBossBaseReward
        player.wbInfo.times = (player.wbInfo.times || 0) + 1
        player.wbInfo.totalTimes = (player.wbInfo.totalTimes || 0) + 1
        player.wbInfo.todayTimes = (player.wbInfo.todayTimes || 0) + 1
        items.forEach(item => {
            bagHandle.AddItem(player.bag, item[0], item[1], random)
        })
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    updateWorldBossInfo(totalDamage: number, mapId: number, gameRouteData?: GameRouteData) {
        let { player, random, dayTime, time } = gameRouteData
        player.wbInfo.progress = player.wbInfo.progress > totalDamage ? player.wbInfo.progress : totalDamage

        let data = [], triggerDamage = 0, num = 0, newData = []
        let reward = mapId == 100302 ? gameConfig.map.wbReward2 : gameConfig.map.wbReward
        let entries = Object.entries(reward)
        entries.forEach((e, i) => {
            let damage = Number(e[0])
            if (totalDamage > damage && damage > triggerDamage) {
                data = e[1]
                triggerDamage = damage
                num = i
            }
        })
        // 道具
        data.forEach(item => {
            let itemID = item[0]
            let itemAmount = item[1]
            if (itemID == "diamond") {
                gameUtils.setPlayerTestInfo(player, "getMailaddGold", item[1], 1)
                player.itemInfo.diamond += item[1]
                newData.push(['gem', itemAmount])
            } else if (itemID == "gold") {
                player.itemInfo.gold += item[1]
                newData.push(['gold', itemAmount])
            } else if (itemID == "gem") {
                let entries = Object.entries(gameConfig.items).filter(i => i[1]['kind'] == ItemType.Gem)
                let amount = item[1] || 1
                let hp = item[2] || 1
                for (let i = 0; i < amount; i++) {
                    let entry: [string, any] = utils.getOneFromArray(entries, random);
                    let tID = Number(entry[0])
                    let gem = new ItemModel({ tID, hp, stack: 1 })
                    bagHandle.AddItemComponent(player.bag, gem)
                    newData.push([tID, 1, hp])
                }
            } else {
                let id = Number(itemID)
                if (gameConfigHandle.gameConfig.items[id]) {
                    bagHandle.AddItem(player.bag, id, itemAmount, random)
                    newData.push([id, itemAmount])
                }

            }
        })
        // 宝物
        let tid, quality, lvl = 1
        if (num <= 3) {
            tid = utils.getOneFromArray(gameConfig.map.wbTreasureReward, random)
            let max = random.intn(100)
            if (max <= 5) {
                quality = random.intn(3) + 2
            } else {
                quality = random.intn(2) + 2
            }
        } else {
            tid = utils.getOneFromArray(gameConfig.map.wbTreasureReward, random)
            quality = random.intn(2) + 1
        }
        let treasure = treasureHandle.createTreasure(tid, lvl, random, quality)
        bagHandle.AddItemComponent(player.treasureBag, treasure)
        newData.push([tid, quality, lvl])
        // 城镇基石
        let isDrop = random.intn(100) < gameConfig.town.deepDropTowItemRate
        if (isDrop) {
            let amount = random.intn(2)
            bagHandle.AddItem(player.bag, gameConfig.town.dropTonwItemID, amount, random)
            newData.push([gameConfig.town.dropTonwItemID, amount])
        }
        // 重置时间
        player.wbInfo.expireTime = time + gameConfig.map.wbFastTime
        return {
            err: 0,
            data: newData,
        }
    }

    @localApi('normalRoute')
    putOnTreasure(itemPos, pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let item = player.treasureBag.items[itemPos]
        if (!item) {
            return {
                err: 1
            }
        }
        let partner = player.teamList.list[pIndex]
        if (!partner) {
            return {
                err: 2
            }
        }
        let itemConfig = gameConfigHandle.configByID[item.tID]
        let orginItem = partner.treasure.items[itemConfig.part]
        partner.treasure.items[itemConfig.part] = item
        bagHandle.removeItemByPosition(player.treasureBag, item.pos)
        if (orginItem) {
            bagHandle.AddItemComponent(player.treasureBag, orginItem)
        }
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    putOffTreasure(part, pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let partner = player.teamList.list[pIndex]
        if (!partner) {
            return {
                err: 1
            }
        }
        let orginItem = partner.treasure.items[part]
        if (orginItem && bagHandle.IsHasEmpty(player.treasureBag, 1)) {
            partner.treasure.items[part] = null
            bagHandle.AddItemComponent(player.treasureBag, orginItem)
        } else {
            return {
                err: 2
            }
        }
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    eatTreasure(bagIndex: number, eatIndex: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let treasureItem = player.treasureBag.items[bagIndex]
        let eatItem: ItemModel = player.treasureBag.items[eatIndex]
        if (!eatItem || !treasureItem) {
            return { err: 1 }
        }
        let maxLvl = gameConfigHandle.gameConfig.treasure.maxLvl
        let treasureLvl = treasureItem.treasure.lvl
        if (treasureLvl >= maxLvl) {
            return { err: 2 }
        }

        if (eatItem.lock) {
            return { err: 3 }
        }
        let eatValues = gameConfigHandle.gameConfig.treasure.eatTreasureExp
        let addExp = utils.getIncValue(eatValues, eatItem.treasure.quality - 1)
        let needExp = 0
        gameConfig.treasure.lvlUpNeed.resourceItems.forEach(r => {
            if (r.itemID == 'exp') {
                needExp = utils.getIncValue2(r.amount, treasureLvl - 1)
            }
        });
        player.treasureBag.items[bagIndex].treasure.exp += addExp
        let upFlag = false
        if (player.treasureBag.items[bagIndex].treasure.exp >= needExp) {
            player.treasureBag.items[bagIndex].treasure.exp -= needExp
            player.treasureBag.items[bagIndex].treasure.lvl += 1
            upFlag = true
        }
        bagHandle.removeItemByPosition(player.treasureBag, eatItem.pos)
        return { err: 0, data: upFlag }
    }

    @localApi('normalRoute')
    eatTreasureWithDiamond(bagIndex: number, eatIndex: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random } = gamRouteData
        let treasureItem = player.treasureBag.items[bagIndex]
        let eatItem: ItemModel = player.treasureBag.items[eatIndex]
        if (!eatItem || !treasureItem) {
            return { err: 5 }
        }

        if (eatItem.treasure.lvl <= treasureItem.treasure.lvl) {
            return { err: 6 }
        }
        let maxLvl = gameConfigHandle.gameConfig.treasure.maxLvl
        let treasureLvl = treasureItem.treasure.lvl
        if (treasureLvl >= maxLvl) {
            return { err: 7 }
        }

        if (eatItem.lock) {
            return { err: 8 }
        }

        if (eatItem.treasure.lvl <= 1) {
            return { err: 9 }
        }
        let lvl = eatItem.treasure.lvl
        let res = playerHandle.getNeedAndUse(player, gameConfig.town.makeConfig.treatureEatUpNeed, lvl)
        if (res) {
            return {
                err: res
            }
        }
        treasureItem.treasure.lvl = eatItem.treasure.lvl - 1
        bagHandle.removeItemByPosition(player.treasureBag, eatItem.pos)
        return { err: 0, data: true }
    }

    //八卦阵卦位提升
    @localApi('normalRoute')
    treasurePosLvlUp(index: number, pIndex: number, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[pIndex]
        let pLvl = partner.lvl
        let posLvl = partner.treasure.posLvls[index] || 0
        let posLvlMax = gameConfigHandle.gameConfig.treasure.maxLvl
        if (posLvl >= posLvlMax) {
            return { err: 6 }
        }
        if (posLvl >= pLvl / 5) {
            return { err: 5, data: posLvl * 5 + 1 }
        }
        let needConfig = gameConfigHandle.gameConfig.treasure.posUpNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, posLvl + 1)
        if (res != 0) {
            return { err: res }
        }
        partner.treasure.posLvls[index] = posLvl + 1
        //更新角色属性 并刷新显示
        playerHandle.initTeam(player)
        return { err: 0 }
    }

    @localApi('normalRoute')
    talentLvlUp(pIndex, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[pIndex]
        if (partner.talent.lvl >= gameConfig.talent.maxLvl) {
            return {
                err: 5
            }
        }
        let lvl = partner.talent.lvl
        let needConfig = gameConfigHandle.gameConfig.talent.lvlUpNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, lvl + 1, pIndex)
        if (res != 0) {
            return { err: res }
        }
    }

    @localApi('normalRoute')
    talentNodeLvlUp(pIndex, nodeName: string, gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let partner = player.teamList.list[pIndex]
        if (!partner.talent.activeNodes[nodeName] || !partner.talent.activeNodes[nodeName].active) {
            return {
                err: 5
            }
        }
        let nodeConfig = gameConfig.talent.node.find(n => n.name == nodeName)
        if (!nodeConfig) {
            return {
                err: 6
            }
        }
        if (nodeConfig.type !== 'polygon' || partner.talent.activeNodes[nodeName].lvl >= gameConfig.talent.nodeMaxLvl) {
            return {
                err: 7
            }
        }
        let lvl = partner.talent.activeNodes[nodeName].lvl || 1
        let needConfig = gameConfigHandle.gameConfig.talent.nodeLvlUpNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, lvl + 1, pIndex)
        if (res != 0) {
            return { err: res }
        }
        partner.talent.activeNodes[nodeName].lvl += 1
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    refreshBar(flag, gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let addTimesOfAfd = 0
        if (playerHandle.isMember(player, time)) {
            addTimesOfAfd = gameConfigHandle.gameConfig.vip.barTimesOfAfd
        }
        let vip = playerHandle.getVipLvl(player)
        let vipTimes = 0
        if (vip) {
            vipTimes += (gameConfig.vip.addBarTimes[vip] || 0)
        }
        if (player.baseInfo.longVip) {
            vipTimes += gameConfig.vip.barTimesOfLongVip
        }
        let maxTimes = gameConfig.bar.maxRefreshBarTimes + vipTimes + addTimesOfAfd
        let times = player.baseInfo.refreshBarTimes
        let diamondRefreshFlag = false
        if (times >= maxTimes) {
            let needConfig = gameConfig.bar.refreshBarNeed
            let res = playerHandle.getNeedAndUse(player, needConfig, times - maxTimes)
            if (res != 0) {
                return {
                    err: res
                }
            }
            player.baseInfo.diamondRefreshBarTimes += 1
            if (player.baseInfo.diamondRefreshBarTimes >= gameConfig.bar.refreshThrehold) {
                player.baseInfo.diamondRefreshBarTimes = 0
                diamondRefreshFlag = true
            }
        }
        if (flag) {
            player.baseInfo.refreshBarTimes += 1
        }
        player.baseInfo.totalRefreshBarTimes = (player.baseInfo.totalRefreshBarTimes || 0) + 1
        player.barTeamList = []
        let max = 0
        gameConfig.bar.refreshRate.forEach(i => max += i)
        let rolesObject = Object.entries(gameConfig.partners)
        let roles = utils.getRandomArrayNoRepeat(rolesObject, 5, random)
        roles.forEach((r) => {
            let quality = 0
            let maxRate = max
            for (let j = 0; j < gameConfig.bar.refreshRate.length; j++) {
                let rate = gameConfig.bar.refreshRate[j];
                if (random.intn(max) <= rate) {
                    quality = j
                    if (quality >= 5) {
                        quality = quality >= 5 ? (playerHandle.isMember(player, time) ? 5 : 4) : quality
                    }
                    break
                } else {
                    maxRate -= rate
                }
            }
            let point = gameConfig.partner.qualityAttriPoint[quality]
            let attriPoint = { maxHp: 0, attack: 0, attackSpeed: 0, hit: 0, dodge: 0, crit: 0, critHurt: 0, def: 0, recoverHp: 0 }
            if (point > 0) {
                let entries = Object.entries(attriPoint)
                while (point > 0) {
                    let attri = utils.getOneFromArray(entries, random)
                    if (attriPoint[attri[0]] < 5) {
                        attriPoint[attri[0]] += 1
                    }
                    point -= 1
                }
            }
            player.barTeamList.push({ quality, tid: r[0], attriPoint })
        })
        let noHighestQuality = player.barTeamList.findIndex(p => p.quality >= 5) == -1
        if (diamondRefreshFlag && noHighestQuality) {
            let max = 0
            gameConfig.bar.diamondRefreshRate.forEach(i => max += i)
            let maxRate = max
            let one = utils.getOneFromArray(player.barTeamList, random)
            for (let j = 0; j < gameConfig.bar.diamondRefreshRate.length; j++) {
                let rate = gameConfig.bar.diamondRefreshRate[j];
                if (random.intn(maxRate) <= rate) {
                    let q = j >= 5 ? (playerHandle.isMember(player, time) ? 5 : 4) : j
                    one.quality = q
                    let point = gameConfig.partner.qualityAttriPoint[one.quality]
                    let attriPoint = { maxHp: 0, attack: 0, attackSpeed: 0, hit: 0, dodge: 0, crit: 0, critHurt: 0, def: 0, recoverHp: 0 }
                    if (point > 0) {
                        let entries = Object.entries(attriPoint)
                        while (point > 0) {
                            let attri = utils.getOneFromArray(entries, random)
                            if (one.attriPoint[attri[0]] < 5) {
                                one.attriPoint[attri[0]] += 1
                            }
                            point -= 1
                        }
                    }
                    break
                } else {
                    maxRate -= rate
                }
            }
        }
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    goIntoBattle(pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let partner = player.teamList.camp[pIndex]
        if (!partner) {
            return {
                err: 1
            }
        }
        let index = player.teamList.list.findIndex(p => p == null)
        if (index == -1) {
            return {
                err: 2
            }
        }
        let count = 0
        player.teamList.list.forEach(p => {
            if (p && p.tID == partner.tID) {
                count += 1
            }
        })
        if (count >= 2) {
            return { err: 3 }
        }
        player.teamList.camp[pIndex] = null
        player.teamList.list[index] = partner
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    upPartnerQuality(pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let partner = player.teamList.list[pIndex]
        if (!partner) {
            return {
                err: 5
            }
        }
        let quality = partner.quality + 1
        if (quality >= gameConfig.partner.qualityMax) {
            return {
                err: 6
            }
        }
        let res = playerHandle.getNeedAndUse(player, gameConfig.partner.updateQualityNeed, quality)
        if (res != 0) {
            return {
                err: res
            }
        }
        partner.quality += 1
        player.teamList.list[pIndex] = partner
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    releasePartner(pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let partner = player.teamList.list[pIndex]
        if (!partner) {
            return {
                err: 5
            }
        }
        // if (partner.busy) {
        //     return {
        //         err: 9
        //     }
        // }
        let activeEquipment = partner.equipments[partner.equipmentActive]
        let hasEquip = Object.entries(activeEquipment).findIndex(e => {
            return e[0] != null && e[1] != null
        }) != -1
        if (hasEquip) {
            return {
                err: 6
            }
        }
        let treasures = partner.treasure.items
        let hasTreasure = Object.entries(treasures).findIndex(e => {
            return e[0] != null && e[1] != null
        }) != -1
        if (hasTreasure) {
            return {
                err: 6
            }
        }
        let teamSize = player.teamList.list.filter(p => p).length
        if (teamSize == 1) {
            return {
                err: 7
            }
        }
        if (player.teamList.camp.length < 50) {
            let newCamp = new Array(50).fill(null)
            player.teamList.camp.forEach((p, i) => {
                newCamp[i] = p
            })
            player.teamList.camp = newCamp
        }
        let campIndex = player.teamList.camp.findIndex(p => p == null)
        if (campIndex == -1) {
            return {
                err: 8
            }
        }
        let newTeam = new Array(10)
        let index = 0
        player.teamList.list.forEach((p, i) => {
            if (p && partner.index != p.index) {
                newTeam[index] = p
                index++
            }
        })
        player.teamList.list = newTeam
        partner.formationPos = null
        // let pos = Object.entries(player.teamList.pos).find(p => p && p[1] == partner.index)
        // playerHandle.setTeamPos(player, pos[0], null)
        player.teamList.camp[campIndex] = partner
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    upPartner(pIndex, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let partner = player.teamList.camp[pIndex]
        if (!partner) {
            return {
                err: 5
            }
        }

        let unlockPos = partnerHandle.getUnlockTeamPos(player)
        let emptyIndex = player.teamList.list.findIndex((p, i) => !p && unlockPos.findIndex(up => up == i) != -1)
        if (emptyIndex == -1) {
            return {
                err: 6
            }
        }

        if (partner.busy) {
            return {
                err: 7
            }
        }

        let count = 0
        player.teamList.list.forEach(p => {
            if (p && p.tID == partner.tID) {
                count += 1
            }
        })
        if (count >= 2) {
            return { err: 3 }
        }
        let pos = 0
        let emptyArr = new Array(12).fill(1).map(i => pos++)
        player.teamList.list.forEach((p, i) => {
            if (p) {
                emptyArr[p.formationPos] = null
            }
        })
        emptyArr = emptyArr.filter(i => i != null)
        partner.formationPos = emptyArr[0]
        partner.fighter = partnerHandle.createPartnerFighter(player, partner)
        player.teamList.list[emptyIndex] = partner
        player.teamList.camp[pIndex] = null
        let campList = new Array(50).fill(null)
        let idx = 0
        player.teamList.camp.filter(p => p).forEach(p => {
            campList[idx] = p
            idx++
        })
        player.teamList.camp = campList
        playerHandle.initTeam(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    fire(pIndex, gameRouteData?: GameRouteData) {
        let { player, random } = gameRouteData
        let partner = player.teamList.camp[pIndex]
        if (!partner) {
            return {
                err: 5
            }
        }
        let activeEquipment = partner.equipments[partner.equipmentActive]
        let hasEquip = Object.entries(activeEquipment).findIndex(e => {
            return e[0] != null && e[1] != null
        }) != -1
        if (hasEquip) {
            return {
                err: 6
            }
        }
        let lvl = Math.floor(partner.lvl / 5)
        let res = playerHandle.getNeedAndUse(player, gameConfig.partner.fireNeed, lvl)
        if (res != 0) {
            return {
                err: res
            }
        }

        if (partner.busy) {
            return {
                err: 7
            }
        }
        let campList = new Array(50).fill(null)
        let index = 0
        player.teamList.camp.forEach((p, i) => {
            if (p && partner.index != p.index) {
                campList[index] = p
                index++
            }
        })
        player.teamList.camp = campList
        let { itemID, amount } = partnerHandle.getPriceOfPartner(partner)
        bagHandle.AddItem(player.bag, itemID, amount, random)
        return {
            err: 0,
            data: { itemID, amount }
        }
    }

    @localApi('normalRoute')
    treasureMerge(mainIndex: number, subIndex: number[], gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let mainTreasure = player.treasureBag.items[mainIndex]
        if (!mainTreasure) {
            return {
                err: 1
            }
        }
        if (mainTreasure.treasure.quality >= 5) {
            return {
                err: 2
            }
        }
        if (!subIndex || subIndex.length != 2 || subIndex.findIndex(s => s == null) != -1) {
            return {
                err: 3
            }
        }
        for (let i = 0; i < subIndex.length; i++) {
            const subTreasure = player.treasureBag.items[subIndex[i]];
            if (!subTreasure) {
                return {
                    err: 4
                }
            }
            if (subTreasure.treasure.quality != mainTreasure.treasure.quality) {
                return {
                    err: 4
                }
            }
        }
        mainTreasure.treasure.quality += 1
        subIndex.forEach(index => {
            bagHandle.removeItemByPosition(player.treasureBag, index)
        })
        return {
            err: 0,
            data: mainTreasure
        }
    }

    @localApi('normalRoute')
    partnerMerge(mainIndex: number, subIndex: number, campFlag: boolean, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let mainPartner = campFlag ? player.teamList.camp[mainIndex] : player.teamList.list[mainIndex]
        if (!mainPartner) {
            return {
                err: 5
            }
        }
        mainPartner.star = mainPartner.star || 0
        if (mainPartner.star >= gameConfig.partner.maxStar) {
            return {
                err: 6
            }
        }
        let subPartner = player.teamList.camp[subIndex];
        if (subIndex == null || subIndex == undefined || !subPartner) {
            return {
                err: 7
            }
        }
        subPartner.star = subPartner.star || 0
        if (subPartner.star != mainPartner.star) {
            return {
                err: 8
            }
        }
        if (mainPartner.busy || subPartner.busy) {
            return {
                err: 9
            }
        }
        let res = playerHandle.getNeedAndUse(player, gameConfig.partner.starUpNeed, mainPartner.star + 1)
        if (res) {
            return {
                err: res
            }
        }
        mainPartner.star += 1
        player.teamList.camp[subIndex] = null
        // player.teamList.camp = player.teamList.camp.filter((c, i) => i != subIndex)
        playerHandle.initTeam(player)
        return {
            err: 0,
            data: mainPartner
        }
    }

    @localApi('normalRoute')
    partnerExtend(mainIndex: number, subIndex: number, starExtend: boolean, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let mainPartner = player.teamList.camp[mainIndex]
        if (!mainPartner) {
            return {
                err: 5
            }
        }

        let mParam = starExtend ? (mainPartner.star || 0) : (mainPartner.lvl || 1)
        let mLimit = starExtend ? gameConfig.partner.maxStar : gameConfig.partner.maxLvl
        if (mParam >= mLimit) {
            return {
                err: 6
            }
        }
        let subPartner = player.teamList.camp[subIndex];
        if (subIndex == null || subIndex == undefined || !subPartner) {
            return {
                err: 7
            }
        }
        let sParam = starExtend ? (subPartner.star || 0) : (subPartner.lvl || 1)
        if (sParam <= mParam) {
            return {
                err: 8
            }
        }
        if (mainPartner.busy || subPartner.busy) {
            return {
                err: 9
            }
        }
        let lvl = starExtend ? sParam : (Math.floor(subPartner.lvl / 10) || 1)
        let need = starExtend ? gameConfig.partner.extendStarNeed : gameConfig.partner.extendNeed
        let res = playerHandle.getNeedAndUse(player, need, lvl)
        if (res) {
            return {
                err: res
            }
        }
        if (starExtend) {
            mainPartner.star = subPartner.star
            subPartner.star = 0
        } else {
            mainPartner.lvl = subPartner.lvl
            mainPartner.exp = subPartner.exp
            subPartner.lvl = 1
            subPartner.exp = 0
        }

        mainPartner.fighter = partnerHandle.createPartnerFighter(player, mainPartner)
        subPartner.fighter = partnerHandle.createPartnerFighter(player, subPartner)

        return {
            err: 0,
            data: [mainPartner, subPartner]
        }
    }

    @localApi('normalRoute')
    switchAutoSell(gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        player.adventureInfo.autoSellState = !player.adventureInfo.autoSellState
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    resizeTreasureBag(gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        player.treasureBag.emptySize = 0
        for (let i = 0; i < player.treasureBag.items.length; i++) {
            let item = player.treasureBag.items[i];
            if (item && item.treasure) {
                if (!item.treasure.attris || item.treasure.attris.length == 0) {
                    bagHandle.removeItemByPosition(player.treasureBag, item.pos)
                }
            } else if (item && !item.treasure) {
                bagHandle.removeItemByPosition(player.treasureBag, item.pos)
            }
        }
        for (let i = 0; i < (gameConfig.base.bagSize + player.treasureBag.addSize); i++) {
            if (!player.treasureBag.items[i]) {
                player.treasureBag.emptySize += 1
            }
        }
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    campLvlUp(gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let lvl = player.teamList.campLvl || 1
        if (lvl >= gameConfig.partner.campMaxLvl) {
            return {
                err: 101
            }
        }
        let lvlUpNeed = gameConfig.partner.campLvlUpNeed
        let res = playerHandle.getNeedAndUse(player, lvlUpNeed, lvl)
        if (res) {
            return {
                err: res
            }
        }
        player.teamList.campLvl = (player.teamList.campLvl || 1) + 1
        let triggerRefresh = false
        if (player.teamList.campLvl == gameConfig.partner.campTaskLimit) {
            triggerRefresh = true
        }
        return {
            err: 0,
            data: triggerRefresh
        }
    }

    @localApi('normalRoute')
    removeBagItem(id, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        bagHandle.removeItemByItemId(player.bag, id, 1000)
        playerHandle.initBag(player)
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    releasePartnerTask(gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let pIndex = []
        player.task.taskList.forEach(task => {
            if (task && task.partnerList && !task.got) {
                task.partnerList.forEach(pi => {
                    pIndex.push(pi)
                })
            }
        })
        player.teamList.camp.forEach(p => {
            if (p && pIndex.findIndex(pi => pi == p.index) == -1 && p.busy) {
                p.busy = false
            }
        })
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    refreshTask(coutFlag: boolean, gameRouteData?: GameRouteData) {
        let { player, random, time, dayTime } = gameRouteData
        let newRandom = random
        let refreshTimes = player.task.refreshTimes
        let maxTimes = gameConfig.partner.campTaskRefreshTimes
        if (refreshTimes >= maxTimes) {
            return {
                err: 1
            }
        }
        let originTaskList = player.task.taskList
        let completeCount = originTaskList.filter(ot => ot && (ot.completeTime >= time || (ot.completeTime && ot.completeTime <= time && !ot.got))).length
        if (completeCount) {
            return {
                err: 2
            }
        }
        // 
        let campBaseLvl = player.teamList.campLvl - gameConfig.partner.campTaskLimit
        if (campBaseLvl < 0) {
            return {
                err: 3
            }
        }

        let newTaskList: TaskInfo[] = []
        let lvl = Math.floor((player.teamList.campLvl - gameConfig.partner.campTaskLimit) / 10) || 0
        let dayTimes = utils.getIncValue(gameConfig.partner.campTask.dayTimes, 0)
        let tasks: [string, any][] = Object.entries(gameConfig.campTask)
        for (let i = 0; i < dayTimes; i++) {
            if (newTaskList.findIndex(t => t && t.type == TaskType.Diamond) != -1) {
                tasks = tasks.filter(t => t[1].taskType != TaskType.Diamond)
            } else if (newTaskList.findIndex(t => t && t.type == TaskType.Gem) != -1) {
                tasks = tasks.filter(t => t[1].taskType != TaskType.Gem)
            }
            let taskConfig = utils.getOneFromArray(tasks, newRandom)
            let taskTime = utils.getOneFromArray(gameConfig.partner.campTask.times, newRandom)
            let reward = { key: null, value: null, hp: null, quality: null }, value
            if (TaskType.Diamond == taskConfig[1].taskType) {
                value = utils.getIncValue(taskConfig[1].values, lvl)
                reward.key = 'diamond'
                reward.value = Math.floor(value * taskTime * 0.5)
            } else if (TaskType.Gem == taskConfig[1].taskType) {
                let value = utils.getIncValue(taskConfig[1].values, lvl)
                let key = utils.getOneFromArray(taskConfig[1].dropItems, newRandom)
                let hp = newRandom.intn(1) + 1
                reward.key = key
                reward.value = Math.floor(value)
                reward.hp = hp
            } else if (TaskType.Resource == taskConfig[1].taskType) {
                let mapConfig = gameConfigHandle.gameConfig.map
                let key = utils.getOneFromArray(taskConfig[1].dropItems, newRandom)
                // 计算当前掉落
                let value = utils.getIncValue(taskConfig[1].values, lvl)
                value = value / 100 * utils.getIncValue(mapConfig.getResource, lvl)
                reward.key = key
                reward.value = Math.floor(value * taskTime)
            } else if (TaskType.RareResource == taskConfig[1].taskType) {
                let key: any = utils.getOneFromArray(taskConfig[1].dropItems, newRandom)
                let rareValues: any = taskConfig[1].rareValues
                let values = rareValues[key]
                let value = utils.getIncValue(values, lvl)
                reward.key = key
                reward.value = Math.floor(value * taskTime)
            } else if (TaskType.Gold == taskConfig[1].taskType) {
                let key: any = 'gold'
                let value = utils.getIncValue(taskConfig[1].values, lvl)
                let getGold = adventureHandle.getGoldAndExpAmount(player, time)[0]
                value = value / 100 * getGold
                reward.key = key
                reward.value = Math.floor(value * taskTime)
            }
            let task = new TaskInfo({
                taskId: taskConfig[0],
                reward,
                type: taskConfig[1].taskType,
                taskTime: taskTime * 60 * 1000
            })
            newTaskList.push(task)
        }
        player.task.taskList = newTaskList
        if (coutFlag) {
            player.task.refreshTimes = (player.task.refreshTimes || 0) + 1
        }
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    startTask(taskIndex, selected: string[], gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let task = player.task.taskList[taskIndex]
        if (!task) {
            return {
                err: 1
            }
        }
        if (selected.length < 3 || selected.findIndex(s => !s || s == '') != -1) {
            return {
                err: 2
            }
        }
        let check = true
        for (let i = 0; i < selected.length; i++) {
            let index = selected[i]
            let partner = player.teamList.camp.find(p => p && p.index == index)
            if (!partner) {
                check = false
                break
            } else if (partner.busy) {
                check = false
                break
            } else {
                partner.busy = true
            }
        }
        if (!check) {
            return {
                err: 2
            }
        }

        task.completeTime = time + task.taskTime
        task.partnerList = selected
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    getTaskReward(taskIndex, gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let task = player.task.taskList[taskIndex]
        if (!task) {
            return {
                err: 1
            }
        }
        let check = task.completeTime && task.completeTime <= time
        if (!check) {
            return {
                err: 2
            }
        }
        let reward = task.reward
        let { value, rate } = taskHandle.calcCampTaskFinalReward(player, reward, task.partnerList)
        if (reward.key == 'diamond') {
            gameUtils.setPlayerTestInfo(player, "getMailaddGold", value, 1)
            player.itemInfo.diamond += value
        } else if (reward.key == "gold") {
            player.itemInfo.gold += value
        } else {
            let itemConfig = gameConfigHandle.configByID[reward.key]
            if (itemConfig.kind == ItemType.Gem) {
                bagHandle.AddItem(player.bag, reward.key, value, random, reward.hp)
            } else {
                bagHandle.AddItem(player.bag, reward.key, value, random)
            }
        }
        task.got = true
        let plist = task.partnerList
        plist.forEach(pl => {
            if (pl) {
                let partner = player.teamList.camp.find(p => p && p.index == pl)
                if (partner) {
                    partner.busy = false
                }
            }
        })
        task.partnerList = []
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    treasureUpLimit(index, part, pIndex, gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let treasureItem: ItemModel
        if (part) {
            let partner = player.teamList.list[pIndex]
            if (!partner) {
                return {
                    err: 5
                }
            }
            treasureItem = partner.treasure.items[part]
        } else {
            treasureItem = player.treasureBag.items[index]
        }

        let limitLvl = gameConfig.suit.upLimitMinLvl[(treasureItem.treasure.upLvl || 0) + 1]
        if (treasureItem.treasure.lvl < limitLvl) {
            return {
                err: 6,
                data: limitLvl
            }
        }
        if (treasureItem.treasure.upLvl >= gameConfig.treasure.maxLimit) {
            return {
                err: 7,
            }
        }
        let needConfig = gameConfig.suit.upLimitNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, (treasureItem.treasure.upLvl || 0) + 1)
        if (res) {
            return {
                err: res
            }
        }
        treasureItem.treasure.upLvl = (treasureItem.treasure.upLvl || 0) + 1
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    alchemyLvlUp(id: number, gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let config = gameConfigHandle.configByID[id]
        if (!config) {
            return {
                err: 5
            }
        }
        let totalFloor = player.adventureInfo.totalFloor
        let isLimit = config.limit > totalFloor
        if (isLimit) {
            return {
                err: 6
            }
        }
        let lvl = player.alchemyInfo.lvls[id] || 0
        if (lvl >= gameConfig.bar.alchemyMaxLvl) {
            return {
                err: 8
            }
        }
        let entries = Object.entries(config.lvlAndMapLimit)
        for (let i = 0; i < entries.length; i++) {
            let entry = entries[i];
            let aLvl = entry[0]
            let floor: any = entry[1]
            if (lvl >= aLvl && player.adventureInfo.totalFloor < floor) {
                isLimit = false
                break
            }
        }
        if (isLimit) {
            return {
                err: 6
            }
        }
        let buildTimes = player.alchemyInfo.build[id] || null
        if (buildTimes && buildTimes > time) {
            return {
                err: 7
            }
        }
        let needConfig = config.lvlUpNeed
        let res = playerHandle.getNeedAndUse(player, needConfig, lvl + 1)
        if (res) {
            return {
                err: res,
                data: 0
            }
        }
        let needMin = utils.getIncValue(gameConfig.bar.alchemyLvlUpTimes, lvl + 1)
        let completeTime = time + needMin * 60 * 1000
        player.alchemyInfo.build[id] = completeTime
        return {
            err: 0,
            data: needMin
        }
    }

    @localApi('normalRoute')
    alchemyLvlUpComplete(gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let buildInfo = player.alchemyInfo.build
        let entries = Object.entries(buildInfo)
        for (let i = 0; i < entries.length; i++) {
            let entry = entries[i];
            let id = entry[0]
            let completeTime: any = entry[1]
            if (completeTime <= time) {
                delete player.alchemyInfo.build[id]
                player.alchemyInfo.lvls[id] = (player.alchemyInfo.lvls[id] || 0) + 1
            }
        }
        return {
            err: 0,
        }
    }

    @localApi('normalRoute')
    accBuild(id, gameRouteData?: GameRouteData) {
        let { player, random, time } = gameRouteData
        let buildInfo = player.alchemyInfo.build
        let entries = Object.entries(buildInfo)
        let entry = entries.find(entry => entry[0] == id)
        if (!entry) {
            return {
                err: 1
            }
        }
        let completeTime: any = entry[1]
        if (completeTime <= time) {
            return {
                err: 2
            }
        }
        let accTimes = player.alchemyInfo.accelerateTimes || 0
        if (accTimes >= gameConfig.bar.alchemyAccelerateMaxTimes) {
            return {
                err: 3
            }
        }
        completeTime = completeTime - gameConfig.bar.alchemyAccelerateTime * 60 * 1000
        if (completeTime <= 0) {
            delete buildInfo[id]
            player.alchemyInfo.lvls[id] = (player.alchemyInfo.lvls[id] || 0) + 1
        } else {
            player.alchemyInfo.build[id] = completeTime
        }
        player.alchemyInfo.accelerateTimes = accTimes + 1
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    refreshNightKillAmount(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        if (!player.deepInfo['nightProgress']) {
            player.deepInfo['nightProgress'] = 0
        }
        let todayProgress = player.deepInfo.nightTodayProgress || 1
        player.deepInfo.nightTodayProgress = todayProgress + 1
        let times = player.deepInfo.nightTimes || 0
        player.deepInfo.nightTimes = times + 1
        if (player.deepInfo.nightProgress < player.deepInfo.nightTodayProgress) {
            player.deepInfo.nightProgress = player.deepInfo.nightTodayProgress
        }
        let mapID = gameConfigHandle.gameConfig.map.nightMapID
        let mapConfig = gameConfigHandle.configByID[mapID]

        let dropList: any[] = []
        // 宝石
        let gemRate = mapConfig.dropList.gemRate || 10

        if (random.intn(100) <= gemRate) {
            let tID: any = utils.getOneFromArray(mapConfig.dropList.gem, random)
            let stack = random.intn(1) + 1
            let hp = 1
            bagHandle.AddItemComponent(player.bag, new ItemModel({ tID, hp, stack }))
            dropList.push({ name: configByID[tID].name, num: stack, hp })
        }
        // 普通材料
        let normalAmount = random.intn(1) + 1
        let floorLvl = todayProgress
        let normalIds = utils.getRandomArrayNoRepeat(mapConfig.dropList.normalItems, normalAmount, random)
        let amount = utils.getIncValue(gameConfigHandle.gameConfig.map.getResource, floorLvl) * 10
        amount = Math.floor(amount)
        for (let i = 0; i < normalIds.length; i++) {
            let tID: any = normalIds[i]
            bagHandle.AddItem(player.bag, tID, amount, random)
            dropList.push({ name: configByID[tID].name, num: amount })
        }
        // 高级材料
        let rareAmount = random.intn(1) + 1
        let rareIds = utils.getRandomArrayNoRepeat(mapConfig.dropList.rareItems, rareAmount, random)
        let maxAmount = utils.getIncValue([3, 0.1], player.deepInfo.nightTodayProgress)
        for (let i = 0; i < rareIds.length; i++) {
            let amount = random.intn(maxAmount) + 1
            let tID: any = rareIds[i]
            bagHandle.AddItem(player.bag, tID, amount, random)
            dropList.push({ name: configByID[tID].name, num: amount })
        }
        return { err: 0, data: dropList }
    }

    @localApi('normalRoute')
    sweepNight(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        let times = player.deepInfo.nightTimes || 0
        if (player.deepInfo.nightTimes >= gameConfig.map.nightFreeTimes) {
            return {
                err: 1
            }
        }
        player.deepInfo.nightTimes = times + 1
        let progress = player.deepInfo.nightProgress
        let dropList: any[] = []

        for (let i = 0; i < progress; i++) {
            let mapID = gameConfigHandle.gameConfig.map.nightMapID
            let mapConfig = gameConfigHandle.configByID[mapID]
            // 宝石
            let gemRate = mapConfig.dropList.sweepGemRate || 5
            if (random.intn(100) <= gemRate) {
                let tID: any = utils.getOneFromArray(mapConfig.dropList.gem, random)
                let stack = random.intn(1) + 1
                let hp = 1
                bagHandle.AddItemComponent(player.bag, new ItemModel({ tID, hp, stack }))
                let existsIndex = dropList.findIndex(dr => dr.name == configByID[tID].name)
                if (existsIndex != -1) {
                    dropList[existsIndex].num += stack
                } else {
                    dropList.push({ name: configByID[tID].name, num: stack, hp })
                }
            }
            // 普通材料
            let normalAmount = random.intn(1) + 1
            let floorLvl = progress
            let normalIds = utils.getRandomArrayNoRepeat(mapConfig.dropList.normalItems, normalAmount, random)
            let amount = utils.getIncValue(gameConfigHandle.gameConfig.map.getResource, floorLvl) * 10
            amount = Math.floor(amount)
            for (let i = 0; i < normalIds.length; i++) {
                let tID: any = normalIds[i]
                bagHandle.AddItem(player.bag, tID, amount, random)
                let existsIndex = dropList.findIndex(dr => dr.name == configByID[tID].name)
                if (existsIndex != -1) {
                    dropList[existsIndex].num += amount
                } else {
                    dropList.push({ name: configByID[tID].name, num: amount })
                }
            }
            // 高级材料
            let rareAmount = random.intn(1) + 1
            let rareIds = utils.getRandomArrayNoRepeat(mapConfig.dropList.rareItems, rareAmount, random)
            let maxAmount = utils.getIncValue([3, 0.1], player.deepInfo.nightTodayProgress)
            for (let i = 0; i < rareIds.length; i++) {
                let amount = random.intn(maxAmount) + 1
                let tID: any = rareIds[i]
                bagHandle.AddItem(player.bag, tID, amount, random)
                let existsIndex = dropList.findIndex(dr => dr.name == configByID[tID].name)
                if (existsIndex != -1) {
                    dropList[existsIndex].num += amount
                } else {
                    dropList.push({ name: configByID[tID].name, num: amount })
                }
            }
        }
        player.deepInfo.nightTodayProgress = player.deepInfo.nightProgress
        return { err: 0, data: dropList }
    }

    @localApi('normalRoute')
    fixTeamBusy(gamRouteData?: GameRouteData) {
        let { player, time, dayTime, random, } = gamRouteData
        player.teamList.list.forEach(p => {
            if (p && p.busy) {
                p.busy = false
            }
        })
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    linkageActive(index: number, gameRouteData?: GameRouteData) {
        let { player } = gameRouteData
        let linkageActive = player.formation.activeLinkage
        if (index == linkageActive) {
            player.formation.activeLinkage = null
        } else {
            player.formation.activeLinkage = index
        }
        return {
            err: 0
        }
    }

    @localApi('normalRoute')
    washTreasure(index: number, gameRouteData?: GameRouteData) {
        let { player, random } = gameRouteData
        let item = player.treasureBag.items[index]
        if (!item) {
            return {
                err: 7
            }
        }
        let res = playerHandle.getNeedAndUse(player, gameConfig.treasure.washNeed, item.treasure.quality)
        if (res) {
            return {
                err: res
            }
        }
        item = treasureHandle.wash(item, random)
        return {
            err: 0,
            data: item
        }
    }
}

export let normalRoute: NormalRoute = new NormalRoute()
